home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / CONTRSRC.ZIP / SRC / SETUP / WIN2.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1994-09-29  |  40.8 KB  |  951 lines

  1. {***************************************************************************
  2. *  WinDummy : appelé par un Close sur la variable fichier OUTPUT           *
  3. **------------------------------------------------------------------------**
  4. *  Entrée : F = variable fichier Output de type TextRec                    *
  5. *  Sortie : Doit renvoyer 0 par définition (= pas d'erreur)                *
  6. *  Variables globales : néant                                              *
  7. ***************************************************************************}
  8.  
  9. {$F+}    { doit être FAR }
  10.  
  11. function WinDummy( var f : TextRec ) : integer;
  12.  
  13. begin
  14.   WinDummy := 0;    { Retourne systématiquement 0 }
  15. end;
  16.  
  17. {$F-}
  18.  
  19. {***************************************************************************
  20. *  WinWriteln : déclenché par Turbo Pascal lors d'un appel à WRITE ou      *
  21. *               WRITELN associé à la variable fichier OUTPUT               *
  22. **------------------------------------------------------------------------**
  23. *  Entrée : F = variable fichier Output de type TextRec                    *
  24. *  Sortie : Doit renvoyer 0 par définition (= pas d'erreur)                *
  25. *  Variables globales : Write2View/R, WritelnX/RW, WritelnY/RW,            *
  26. *                       WritelnPtr/RW, ViewX1/R, ViewY1/R, ViewX2/R,       *
  27. *                       ViewY2/R                                           *
  28. ***************************************************************************}
  29.  
  30. {$F+}   { Doit être FAR }
  31.  
  32. function WinWriteln( var f : TextRec ) : integer;
  33.  
  34. var i    : integer;    { Compteur d'itérations }
  35.     Carptr : BPTR;     { Pointe sur le caractère à afficher  }
  36.  
  37. begin
  38.   with f do    { Traite la variable fichier }
  39.     begin
  40.       Carptr := BPTR( BufPtr );  { Pointe sur le premier caractère }
  41.       if ( Write2View ) then  { Faut-il tenir compte de la zone de visualisation ? }
  42.         begin  { Oui, fait éventuellement défiler la zone }
  43.           for i := 1 to BufPos do { Parcourt les caractères }
  44.             begin
  45.               case Carptr^ of   { Traite le caractère courant }
  46.  
  47.                 7 : begin    { BEL : Emet un signal sonore }
  48.                       Sound( 880 );  { Lance le signal }
  49.                       Delay( 750 );  { Attend 3/4 seconde }
  50.                       NoSound;   { Coupe le signal }
  51.                     end;
  52.  
  53.                 8 : begin   { Backspace (BS): Revient en arrière }
  54.                       if ( WritelnX = ViewX1 ) then { Début de ligne ? }
  55.                         begin   { Oui, revient à la ligne précédente }
  56.                           WritelnX := ViewX2;  { en dernière colonne }
  57.                           dec( WritelnY );      { de la ligne préc.  }
  58.                         end
  59.                       else   { Même ligne }
  60.                         dec( WritelnX );  { Recule d'une colonne }
  61.                       WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  62.                     end;
  63.  
  64.                10 : begin     { Linefeed (LF): Incrémente la ligne d'affichage  }
  65.                       if ( WritelnY = ViewY2 ) then { Est-ce la dernière ligne de la zone de visualisation ? }
  66.                         WinScrollUp( ViewX1, ViewY1+1, ViewX2,
  67.                                      ViewY2, 1, WritelnCol )
  68.                       else   { Pas besoin de faire défiler la zone de visualisation }
  69.                         begin
  70.                           inc( WritelnY );
  71.                           WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  72.                         end;
  73.                     end;
  74.  
  75.                13 : begin             { CR: Revient au début de la ligne }
  76.                       WritelnX := ViewX1;
  77.                       WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  78.                     end;
  79.  
  80.                else   { Autre caractère : affiche tel quel }
  81.                  begin
  82.                    {-- Ecrit le code ASCII et l'attribut en mémoire vidéo--}
  83.  
  84.                    WritelnPtr^.Caractere := Carptr^;
  85.                    WritelnPtr^.Attribut := WritelnCol;
  86.  
  87.                    {-- Avance le pointeur sur le caractère suivant -------}
  88.  
  89.                    inc( PTRREC( WritelnPtr ).Ofs, 2 );
  90.                    inc( WritelnX );  { Incrémente la colonne }
  91.                    if ( WritelnX > ViewX2 ) then  { Limite de la zone de visualisation ? }
  92.                      begin  { Oui  }
  93.                        WritelnX := ViewX1;  { Ligne suivante }
  94.                        if ( WritelnY = ViewY2 ) then  { Est-ce la dernière de la zone de visualisation ?}
  95.                          begin  { Oui, fait défiler la zone }
  96.                            WinScrollUp( ViewX1, ViewY1+1, ViewX2,
  97.                                         ViewY2, 1, WritelnCol );
  98.                            WritelnX := ViewX1;  { Bord gauche }
  99.  
  100.                            WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  101.                          end
  102.                        else  { Pas besoin de faire défiler la zone de visualisation }
  103.                          begin
  104.                            inc( WritelnY );
  105.                            WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  106.                          end;
  107.                      end;
  108.                  end;
  109.               end;
  110.               inc( PTRREC( Carptr ).Ofs );{ Pointe sur le caractère suivant }
  111.            end;
  112.         end
  113.       else   { Ne tient pas compte de la zone de visualisation , écrit simplement dans la mémoire vidéo }
  114.         begin
  115.           for i := 1 to BufPos do  { Parcourt les caractères }
  116.             begin
  117.               case Carptr^ of   { Traite le caractère courant }
  118.  
  119.                 7 : begin  { BEL : Emet un signal sonore }
  120.                       Sound( 880 ); { Lance le signal  }
  121.                       Delay( 750 ); { Attend 3/4 seconde }
  122.                       NoSound;      { Coupe le signal }
  123.                     end;
  124.  
  125.                 8 : begin  { Backspace (BS): Revient en arrière }
  126.                       if ( WritelnX = 0 ) then { Début de ligne ? }
  127.                         begin          { Oui, revient à la ligne précédente }
  128.                           WritelnX := NbCol - 1;  { en dernière colonne }
  129.                           dec( WritelnY );       { de la ligne }
  130.                         end
  131.                       else                  { Même ligne }
  132.                         dec( WritelnX );     { Recule d'une colonne }
  133.                       WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  134.                     end;
  135.  
  136.                10 : begin     { Linefeed (LF): Incrémente la ligne d'affichage }
  137.                       inc( WritelnY );
  138.                       WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  139.                     end;
  140.  
  141.                13 : begin             { CR: Revient au début de la ligne }
  142.                       WritelnX := 0;
  143.                       WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  144.                     end;
  145.  
  146.                else           { Autre caractère : afficher tel quel }
  147.                  begin
  148.                    {-- Ecrit le code ASCII et l'attribut en mémoire vidéo--}
  149.  
  150.  
  151.                    WritelnPtr^.Caractere := Carptr^;
  152.                    WritelnPtr^.Attribut := WritelnCol;
  153.  
  154.                    {-- Avance le pointeur sur le caractère suivant --------------}
  155.  
  156.                    inc( PTRREC( WritelnPtr ).Ofs, 2 );
  157.                    inc( WritelnX );   { Incrémente la colonne }
  158.                    if ( WritelnX = NbCol ) then    { Fin de ligne ? }
  159.                      begin   { Oui  }
  160.                        WritelnX := 0;   { Passe à la suivante }
  161.                        inc( WritelnY );
  162.                      end;
  163.                  end;
  164.               end;
  165.               inc( PTRREC( Carptr ).Ofs );{ Pointe sur le caractère suivant }
  166.            end;
  167.         end;
  168.       BufPos := 0;    { Tous les caractères ont été traités }
  169.     end;
  170.   WinWriteln := 0;  { Retourne 0 }
  171. end;
  172.  
  173. {$F-}
  174.  
  175. {***************************************************************************
  176. *  OutputOpen : déclenché par Turbo Pascal au premier appel de WRITE       *
  177. *               ou de WRITELN, après que la variable fichier Output        *
  178. *               ait été détournée par WinInit                              *
  179. **------------------------------------------------------------------------**
  180. *  Entrée : F = variable fichier Output de type TextRec                    *
  181. *  Sortie : Doit renvoyer 0 par définition (= pas d'erreur)                *
  182. *  Variables globales : néant *                                            *
  183. ****************************************************************************}
  184.  
  185. {$F+} { Doit être FAR }
  186.  
  187. function OutputOpen( var f : TextRec ) : integer;
  188.  
  189. begin
  190.   with f do      { Traite la variable fichier }
  191.     begin
  192.       InOutFunc := @WinWriteln; { Fixe l'adresse de la fonction de sortie }
  193.       FlushFunc := @WinWriteln; { "Flush" correspond ici à "Out" }
  194.       CloseFunc := @WinDummy;   { Close n'est pas pris en compte  }
  195.     end;
  196.   OutputOpen := 0;  { Retourne systématiquement 0 }
  197. end;
  198.  
  199. {$F-}
  200.  
  201. {**************************************************************************
  202. *  ScrollHori : fait défiler une zone de l'écran                          *
  203. *               d'un certain nombre de colonnes                           *
  204. *               vers la gauche ou la droite                               *
  205. **-----------------------------------------------------------------------**
  206. *  Entrées :x1, y1    = Coordonnées du coin supérieur gauche de la zone   *
  207. *           x2, y2    = Coordonnées du coin unférieur droit de la zone    *
  208. *           Nombre    = Nombre de colonnes à décaler                      *
  209. *           Couleur   = Couleur où attribut des colonnes libérées         *
  210. *           AGauche   = TRUE  : Défilement vers la gauche                 *
  211. *                       FALSE : Défilement vers la droite                 *
  212. *  Information        : Si la couleur est égale à la constante NO_CLEAR,  *
  213. *                       les colonnes libérées ne sont pas effacées        *
  214. *  Variable globale   : LigneOfs/R                                        *
  215. **************************************************************************}
  216.  
  217. procedure ScrollHori( x1, y1, x2, y2, Nombre, Couleur : byte;
  218.                          AGauche : boolean );
  219.  
  220. var de,         { Copie de ... }
  221.     a   : VPTR; { ... à }
  222.     Byte2Copy,  { Nombre d'octets par ligne }
  223.     ActLigne  : integer;   { Ligne actuelle }
  224.  
  225. begin
  226.  Byte2Copy := (x2 - x1 + 1) shl 1;  { Nombre d'octets }
  227.  de := GetVioPtr( x1, y1 );
  228.  if AGauche then     { Vers la gauche ?  }
  229.    a := GetVioPtr( x1 - Nombre, y1 ) { Oui }
  230.  else    { Vers la droite  }
  231.    a := GetVioPtr( x1 + Nombre, y1 );
  232.  
  233.  for ActLigne := y1 to y2 do    {  Parcourt les lignes }
  234.    begin
  235.      Move( de^, a^, Byte2Copy );  { Copie la ligne }
  236.      inc( PTRREC( de ).Ofs, LigneOfs );
  237.      inc( PTRREC( a ).Ofs, LigneOfs );
  238.    end;
  239.  
  240.  {-- Efface éventuellement les colonnes libérées -----}
  241.  
  242.  if Couleur <> NO_CLEAR then  { Efface ?  }
  243.   if AGauche then   { Vers la gauche  }
  244.     WinFill( x2-Nombre+1, y1, x2, y2, ' ', Couleur)
  245.   else   { Vers la droite }
  246.     WinFill( x1, y1, x1+Nombre-1, y2, ' ', Couleur);
  247. end;
  248.  
  249. {**************************************************************************
  250. *  WinScrollDown : fait défiler une zone de l'écran                       *
  251. *                 d'un certain nombre de lignes vers le bas               *
  252. **-----------------------------------------------------------------------**
  253. *  Entrées : x1, y1 = Coordonnées du coin supérieur gauche de la zone     *
  254. *            x2, y2 = Coordonnées du coin inférieur droit de la zone      *
  255. *            Nombre = Nombre de lignes à remonter                         *
  256. *            Couleur = Couleur ou attribut des lignes libérées            *
  257. *  Information    : Si la couleur est égale à la constante NO_CLEAR,      *
  258. *            les lignes libérées ne sont pas effacées                     *
  259. *  Variables globales : LigneOfs/R                                        *
  260. **************************************************************************}
  261.  
  262. procedure WinScrollDown( x1, y1, x2, y2, Nombre, Couleur : byte );
  263.  
  264. var de,    { Copie de ...}
  265.     a    : VPTR;   { ... à }
  266.     Byte2Copy,   { Nombre d'octets par ligne }
  267.     ActLigne  : integer; { Ligne actuelle }
  268.  
  269. begin
  270.  Byte2Copy := (x2 - x1 + 1) shl 1;   { Nombre d'octets }
  271.  de  := GetVioPtr( x1, y2 );  { Pointe sur la ligne à déplacer }
  272.  a   := GetVioPtr( x1, y2 + Nombre );  { Nouvelle position }
  273.  
  274.  for ActLigne := y1 to y2 do    { Parcourt les différentes lignes  }
  275.    begin
  276.      Move( de^,a^, Byte2Copy ); { Copie la ligne }
  277.      dec( PTRREC( de ).Ofs, LigneOfs );
  278.      dec( PTRREC( a  ).Ofs, LigneOfs );
  279.    end;
  280.  
  281.  if Couleur <> NO_CLEAR then  { Efface les lignes libérées ? }
  282.    WinFill( x1, y1, x2, y1+Nombre-1, ' ', Couleur);    { Oui }
  283. end;
  284.  
  285. {**************************************************************************
  286. *  WinScrollUp : fait défiler une zone de l'écran                         *
  287. *                 d'un certain nombre de lignes vers le haut              *
  288. **-----------------------------------------------------------------------**
  289. *  Entrées : x1, y1 = Coordonnées du coin supérieur gauche de la zone     *
  290. *            x2, y2 = Coordonnées du coin inférieur droit de la zone      *
  291. *            Nombre = Nombre de lignes à remonter                         *
  292. *            Couleur = Couleur ou attribut des lignes libéréess           *
  293. *  Information    : Si la couleur est égale à la constante NO_CLEAR,      *
  294. *            les lignes libérées ne sont pas effacées                     *
  295. *  Variables globales : LigneOfs/R                                        *
  296. ***************************************************************************}
  297.  
  298. procedure WinScrollUp( x1, y1, x2, y2, Nombre, Couleur : byte );
  299.  
  300. var de,     { Copie de ... }
  301.     a      : VPTR;   { ... à }
  302.     Byte2Copy,    { Nombre d'octets par ligne }
  303.     ActLigne  : integer; { Ligne actuelle }
  304.  
  305. begin
  306.  Byte2Copy := (x2 - x1 + 1) shl 1;   { Nombre d'octets }
  307.  de   := GetVioPtr( x1, y1 );    { Pointe sur la ligne à déplacer }
  308.  a    := GetVioPtr( x1, y1 - Nombre ); { Nouvelle position}
  309.  
  310.  for ActLigne := y1 to y2 do  { Parcourt les différents caractères }
  311.    begin
  312.      Move( de^,a^, Byte2Copy );  { Copie la ligne }
  313.      inc( PTRREC( de  ).Ofs, LigneOfs );
  314.      inc( PTRREC( a  ).Ofs, LigneOfs );
  315.    end;
  316.  
  317.  if Couleur <> NO_CLEAR then   { Efface les lignes libérées ? }
  318.    WinFill( x1, y2+1-Nombre, x2, y2, ' ', Couleur);    { Oui }
  319. end;
  320.  
  321. {***************************************************************************
  322. *  WinScrollLeft : fait défiler une zone de l'écran                        *
  323. *                  d'une certain nombre de colonnes vers la gauche         *
  324. **------------------------------------------------------------------------**
  325. *  Entrées : cf WinScrollUp, WinScrollDown                                 *
  326. *  Variables globales : néant                                              *
  327. ***************************************************************************}
  328.  
  329. procedure WinScrollLeft( x1, y1, x2, y2, Nombre, Couleur : byte );
  330.  
  331. begin
  332.   ScrollHori( x1, y1, x2, y2, Nombre, Couleur, TRUE );
  333. end;
  334.  
  335. {***************************************************************************
  336. *  WinScrollRight: fait défiler une zone de l'écran                        *
  337. *                  d'un certain nombre de colonnes vers la droite          *
  338. **------------------------------------------------------------------------**
  339. *  Entrées : cf WinScrollUp, WinScrollDown                                 *
  340. *  Variables globales : néant                                              *
  341. ***************************************************************************}
  342.  
  343. procedure WinScrollRight( x1, y1, x2, y2, Nombre, Couleur : byte );
  344.  
  345. begin
  346.   ScrollHori( x1, y1, x2, y2, Nombre, Couleur, FALSE );
  347. end;
  348.  
  349. {***************************************************************************
  350. *  WinMoveUp : déplace la fenêtre active vers le haut                      *
  351. **------------------------------------------------------------------------**
  352. *  Entrée : Nombre = Nombre de lignes du déplacement                       *
  353. *  Information     : le programme appelant doit s'assurer que la fenêtre   *
  354. *                    ne sort pas des limites de l'écran                    *
  355. *  Variables globales : vLigne/RW, vColonne/RW, Write2View/R, ViewY1/W,    *
  356. *                       ViewY2/W, WritelnY/W                               *
  357. ***************************************************************************}
  358.  
  359. procedure WinMoveUp( Nombre : byte );
  360.  
  361. var BufPtr : VPTR;  { Pointe sur un buffer de travail }
  362.     Largeur,  { Nombre de colonnes de la fenêtre }
  363.     Hauteur,  { Nombre de lignes de la fenêtre }
  364.     BufLen : integer;  { Taille du buffer de travail en octets }
  365.  
  366. {-- GetPtr est une fonction locale qui renvoie un pointeur sur le début d'une ligne dans le buffer de la fenêtre active --}
  367.  
  368. function GetPtr( Ligne : integer ) : pointer;
  369.  
  370. begin
  371.   GetPtr := @ActBufPtr^[ Ligne * Largeur ];
  372. end;
  373.  
  374. {-------------------------------------------------------------------------}
  375.  
  376. begin
  377.   with ActWinPtr^ do    { Accède au descripteur de la fenêtre active }
  378.     begin
  379.       Largeur := x2 - x1 + 1;
  380.       Hauteur := y2 - y1 + 1;
  381.       BufLen := Largeur * Nombre shl 1;
  382.       GetMem( BufPtr, BufLen );   { Alloue un buffer temporaire }
  383.       GetScr( x1, y1-Nombre, x2, y1-1, BufPtr );
  384.       WinScrollUp ( x1, y1, x2, y2, Nombre, NO_CLEAR );
  385.       PutScr( x1, y2-Nombre+1, x2, y2, GetPtr( Hauteur - Nombre ) );
  386.       Move( GetPtr( 0 )^, GetPtr(Nombre)^, Largeur * (Hauteur-Nombre) shl 1);
  387.       Move( BufPtr^, GetPtr( 0 )^, BufLen );
  388.  
  389.       {-- Si le curseur se trouve à l'intérieur de la fenêtre, il doit  -}
  390.       {-- aussi être déplacé                                            -}
  391.  
  392.       if ( (x1 <= vColonne ) and (x2 >= vColonne ) and
  393.            (y1 <= vLigne ) and (y2 >= vLigne ) ) then
  394.         WinSetCursor( vColonne , vLigne - Nombre );
  395.  
  396.       {-- En mode Write2View, la position d'affichage pour Write et ------}
  397.       {-- Writeln doit être recalée -------}
  398.  
  399.       if ( Write2View ) then   { Est-on en mode Write2View ? }
  400.         begin   { Oui  }
  401.           dec( WritelnY, Nombre );   { Ajuste la position }
  402.           WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  403.         end;
  404.  
  405.       dec( y1, Nombre );    { Met à jour les coordonnées de la fenêtre }
  406.       dec( y2, Nombre );
  407.       FreeMem( BufPtr, BufLen ); { Libère le buffer temporaire }
  408.     end;
  409.   dec( ViewY1, Nombre );   { Déplace la zone de visualisation }
  410.   dec( ViewY2, Nombre );
  411. end;
  412.  
  413. {***************************************************************************
  414. *  WinMoveDown : déplace la fenêtre active vers le bas                     *
  415. *                                                                          *
  416. **------------------------------------------------------------------------**
  417. *  Entrée : Nombre = Nombre de lignes du déplacement                       *
  418. *  Information    : le programme appelant doit s'assurer que la fenêtre ne *
  419. *                   sort pas des limites de l'écran                        *
  420. *  Variables globales : vLigne/RW, vColonne/RW, Write2View/R, ViewY1/W,    *
  421. *                       ViewY2/W, WritelnY/W                               *
  422. ***************************************************************************}
  423.  
  424. procedure WinMoveDown( Nombre : byte );
  425.  
  426. var BufPtr : VPTR;  { Pointe sur un buffer de travail }
  427.     Largeur,   { Nombre de colonnes de la fenêtre }
  428.     Hauteur,   { Nombre de lignes de la fenêtre }
  429.     BufLen : integer;  { Taille du buffer de travail en octets }
  430.  
  431. {-- GetPtr est une fonction locale qui retourne un pointeur sur le début d'une ligne dans le buffer de la fenêtre active -- }
  432.  
  433. function GetPtr( Ligne : integer ) : pointer;
  434.  
  435. begin
  436.   GetPtr := @ActBufPtr^[ Ligne * Largeur ];
  437. end;
  438.  
  439. {--------------------------------------------------------------------------}
  440.  
  441. begin
  442.   with ActWinPtr^ do  { Accède au descripteur de la fenêtre active }
  443.     begin
  444.       Largeur := x2 - x1 + 1;
  445.       Hauteur := y2 - y1 + 1;
  446.       BufLen := Largeur * Nombre shl 1;
  447.       GetMem( BufPtr, BufLen );  { Alloue un buffer temporaire }
  448.       GetScr( x1, y2+1, x2, y2+Nombre, BufPtr );
  449.       WinScrollDown( x1, y1, x2, y2, Nombre, NO_CLEAR );
  450.       PutScr( x1, y1, x2, y1+Nombre-1, GetPtr( 0 ) );
  451.       Move( GetPtr(Nombre)^, GetPtr( 0 )^, Largeur * (Hauteur-Nombre) shl 1);
  452.       Move( BufPtr^, GetPtr( Hauteur - Nombre )^, BufLen );
  453.  
  454.       {-- Si le curseur se trouve à l'intérieur de la fenêtre, il doit  -}
  455.       {-- aussi être déplacé                                            -}
  456.  
  457.       if ( (x1 <= vColonne ) and (x2 >= vColonne ) and
  458.            (y1 <= vLigne ) and (y2 >= vLigne ) ) then
  459.         WinSetCursor( vColonne , vLigne + Nombre );
  460.  
  461.       {-- En mode Write2View, la position d'affichage pour Write et ------}
  462.       {-- Writeln doit être recalée -------}
  463.  
  464.       if ( Write2View ) then  { Est-on en mode Write2View ? }
  465.         begin  { Oui }
  466.           inc( WritelnY, Nombre );   { Ajuste la position }
  467.           WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  468.         end;
  469.  
  470.       inc( y1, Nombre ); { Met à jour les coordonnées de la fenêtre }
  471.       inc( y2, Nombre );
  472.       FreeMem( BufPtr, BufLen );  { Libère le buffer temporaire }
  473.     end;
  474.   inc( ViewY1, Nombre );   { Déplace la zone de visualisation  }
  475.   inc( ViewY2, Nombre );   
  476. end;
  477.  
  478. {***************************************************************************
  479. *  WinMoveRight : déplace la fenêtre active vers la droite                 *
  480. **------------------------------------------------------------------------**
  481. *  Entrée : Nombre = Nombre de colonnes du déplacement                     *
  482. *  Information    : le programme appelant doit s'assurer que la fenêtre ne *
  483. *                   sort pas des limites de l'écran                        *
  484. *  Variables globales : vLigne/RW, vColonne/RW, Write2View/R, ViewX1/W,    *
  485. *                       ViewX2/W, WritelnX/W                               *
  486. ***************************************************************************}
  487.  
  488. procedure WinMoveRight( Nombre : byte );
  489.  
  490. var BufPtr,   { Pointe sur un buffer de travail }
  491.     LBufPtr   : VPTR;  { Pointeur courant }
  492.    Byte2Copy,  { Nombre d'octets à copier }
  493.     Ligne,     { Compteur de lignes }
  494.     EndLigne,  { idem }
  495.     Largeur,   { Nombre de colonnes de la fenêtre }
  496.     Hauteur,   { Nombre de lignes de la fenêtre }
  497.     BufLen    : integer;  { Taille du buffer de travail en octets }
  498.  
  499. {-- GetPtr est une fonction locale qui retourne un pointeur sur le début d'une ligne dans le buffer de la fenêtre active -- }
  500.  
  501. function GetPtr( Ligne, Colonne : integer ) : pointer;
  502.  
  503. begin
  504.   GetPtr := @ActBufPtr^[ Ligne * Largeur + Colonne ];
  505. end;
  506.  
  507. {-------------------------------------------------------------------------}
  508.  
  509. begin
  510.   with ActWinPtr^ do   { Accède à la fenêtre active }
  511.     begin
  512.       Largeur := x2 - x1 + 1;
  513.       Hauteur := y2 - y1 + 1;
  514.       BufLen := Hauteur * Nombre shl 1;
  515.       GetMem( BufPtr, BufLen );  { Alloue un buffer temporaire }
  516.       GetScr( x2+1, y1, x2+Nombre, y2, BufPtr );
  517.       ScrollHori( x1, y1, x2, y2, Nombre, NO_CLEAR, FALSE );
  518.  
  519.       Byte2Copy := ( Largeur - Nombre ) shl 1;
  520.       LBufPtr := BufPtr;   { Pointe sur le début du buffer }
  521.       EndLigne := Hauteur - 1;
  522.       for Ligne:=0 to EndLigne do  { Parcourt les lignes une à une }
  523.         begin
  524.           PutScr( x1, Ligne+y1, x1+Nombre-1, Ligne+y1,
  525.                         GetPtr( Ligne, 0 ) );
  526.           Move( GetPtr( Ligne, Nombre )^, GetPtr( Ligne, 0 )^, Byte2Copy );
  527.           Move( LBufPtr^, GetPtr( Ligne, Largeur - Nombre )^, Nombre shl 1 );
  528.           inc( PTRREC( LBufPtr ).Ofs, Nombre shl 1 );
  529.         end;
  530.  
  531.       {-- Si le curseur se trouve à l'intérieur de la fenêtre, il doit  -}
  532.       {-- aussi être déplacé                                            -}
  533.  
  534.       if ( (x1 <= vColonne ) and (x2 >= vColonne ) and
  535.            (y1 <= vLigne ) and (y2 >= vLigne ) ) then
  536.         WinSetCursor( vColonne + Nombre , vLigne );
  537.  
  538.       {-- En mode Write2View, la position d'affichage pour Write et ------}
  539.       {-- Writeln doit être recalée -------}
  540.  
  541.       if ( Write2View ) then   { Est-on en mode Write2View ? }
  542.         begin  { Oui }
  543.           inc( WritelnX, Nombre );  { Ajuste la position d'affichage }
  544.           WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  545.         end;
  546.  
  547.       inc( x1, Nombre ); { Met à jour les coordonnées de la fenêtre }
  548.       inc( x2, Nombre );
  549.       FreeMem( BufPtr, BufLen ); { Libère le buffer temporaire }
  550.     end;
  551.   inc( ViewX1, Nombre );   { Déplace la zone de visualisation }
  552.   inc( ViewX2, Nombre );
  553. end;
  554.  
  555. {***************************************************************************
  556. *  WinMoveLeft : déplace la fenêtre active vers la gauche                  *
  557. **------------------------------------------------------------------------**
  558. *  Entrée : Nombre = Nombre de colonnes du déplacement                     *
  559. *  Information    : le programme appelant doit s'assurer que la fenêtre ne *
  560. *                   sort pas des limites de l'écran                        *
  561. *  Variables globales : vLigne/RW, vColonne/RW, Write2View/R, ViewX1/W,    *
  562. *                       ViewX2/W, WritelnX/W                               *
  563. ***************************************************************************}
  564.  
  565. procedure WinMoveLeft( Nombre : byte );
  566.  
  567. var BufPtr,   { Pointe sur un buffer de travail }
  568.     LBufPtr   : VPTR;  { Pointeur courant }
  569.     Byte2Copy,  { Nombre d'octets à copier }
  570.     Ligne,      { Compteur de lignes }
  571.     EndLigne,   { idem }
  572.     Largeur,    { Nombre de colonnes de la fenêtre }
  573.     Hauteur,    { Nombre de lignes de la fenêtre }
  574.     BufLen    : integer;   { Taille du buffer de travail en octets }
  575.  
  576. {-- GetPtr est une fonction locale qui retourne un pointeur sur le début d'une ligne dans le buffer de la fenêtre active -- }
  577.  
  578. function GetPtr( Ligne, Colonne : integer ) : pointer;
  579.  
  580. begin
  581.   GetPtr := @ActBufPtr^[ Ligne * Largeur + Colonne ];
  582. end;
  583.  
  584. {-------------------------------------------------------------------------}
  585.  
  586. begin
  587.   with ActWinPtr^ do  { Accède au descripteur de la fenêtre active }
  588.     begin
  589.       Largeur := x2 - x1 + 1;
  590.       Hauteur := y2 - y1 + 1;
  591.       BufLen := Hauteur * Nombre shl 1;
  592.       GetMem( BufPtr, BufLen ); { Alloue un buffer temporaire }
  593.       GetScr( x1-Nombre, y1, x1-1, y2, BufPtr );
  594.       ScrollHori( x1, y1, x2, y2, Nombre, NO_CLEAR, TRUE );
  595.  
  596.       Byte2Copy := ( Largeur - Nombre ) shl 1;
  597.       LBufPtr := BufPtr;  { Pointe sur le début du buffer }
  598.       EndLigne := Hauteur - 1;
  599.       for Ligne:=0 to EndLigne do  { Parcourt les lignes une à une  }
  600.         begin
  601.           PutScr( x2-Nombre+1, Ligne+y1, x2, Ligne+y1,
  602.                         GetPtr( Ligne, Largeur - Nombre ) );
  603.           Move( GetPtr( Ligne, 0 )^, GetPtr( Ligne, Nombre )^, Byte2Copy );
  604.           Move( LBufPtr^, GetPtr( Ligne, 0 )^, Nombre shl 1 );
  605.           inc( PTRREC( LBufPtr ).Ofs, Nombre shl 1 );
  606.         end;
  607.  
  608.       {-- Si le curseur se trouve à l'intérieur de la fenêtre, il doit  -}
  609.       {-- aussi être déplacé                                            -}
  610.  
  611.       if ( (x1 <= vColonne ) and (x2 >= vColonne ) and
  612.            (y1 <= vLigne ) and (y2 >= vLigne ) ) then
  613.         WinSetCursor( vColonne + Nombre , vLigne );
  614.  
  615.       {-- En mode Write2View, la position d'affichage pour Write et ------}
  616.       {-- Writeln doit être recalée -------}
  617.  
  618.       if ( Write2View ) then   { Est-on en mode Write2View ? }
  619.         begin   { Oui }
  620.           dec( WritelnX, Nombre );  { Ajuste la position }
  621.           WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  622.         end;
  623.  
  624.       dec( x1, Nombre ); { Met à jour les coordonnées de la fenêtre }
  625.       dec( x2, Nombre );
  626.       FreeMem( BufPtr, BufLen );  { Libère le buffer temporaire }
  627.     end;
  628.   dec( ViewX1, Nombre );  { Déplace la zone de visualisation }
  629.   dec( ViewX2, Nombre );
  630. end;
  631.  
  632. {***************************************************************************
  633. *  WinMove : déplace la fenêtre active                                     *
  634. *                                                                          *
  635. **------------------------------------------------------------------------**
  636. *  Entrées : x, y : Nouvelles coordonnées du coin supérieur gauche de la   *
  637. *                   fenêtre                                                *
  638. *  Information    : le programme appelant doit s'assurer que la fenêtre ne *
  639. *                   sort pas des limites de l'écran                        *
  640. *  Variables globales : vLigne/RW, vColonne/RW, Write2View/R, ViewX1/W,    *
  641. *                     ViewX2/W, ViewY1/W, ViewY2/W, WritelnX/W, WritelnY/W *
  642. *  Variable globale : néant                                                *
  643. ***************************************************************************}
  644.  
  645. procedure WinMove( x, y : byte );
  646.  
  647. var BufPtr : VPTR;   { Pointe sur un buffer temporaire }
  648.     DeltaX,      { Distance entre l'ancienne et la nouvelle }
  649.     DeltaY,      { position de la fenêtre }
  650.     Largeur,     { Nombre de colonnes de la fenêtre }
  651.     Hauteur,     { Nombre de lignes de la fenêtre }
  652.     BufLen : integer;  { Taille du buffer temporaire en octet }
  653.  
  654. begin
  655.   with ActWinPtr^ do  { Accède au descripteur de la fenêtre active }
  656.     begin
  657.       Largeur := x2 - x1;
  658.       Hauteur := y2 - y1;
  659.       BufLen := ( Hauteur + 1 ) * ( Largeur + 1 ) shl 1;
  660.       GetMem( BufPtr, BufLen ); { Alloue un buffer temporaire }
  661.       GetScr( x1, y1, x2, y2, BufPtr ); { Stocke la fenêtre active dans le tampon }
  662.       PutScr( x1, y1, x2, y2, @Buffer ); { Restaure la zone recouverte }
  663.  
  664.       DeltaX := x - x1;   { Distance en nombre de colonnes }
  665.       DeltaY := y - y1;   { Distance en nombre de lignes }
  666.  
  667.       {-- Si le curseur se trouve à l'intérieur de la fenêtre, il doit  -}
  668.       {-- aussi être déplacé                                            -}
  669.  
  670.       if ( (x1 <= vColonne ) and (x2 >= vColonne ) and
  671.            (y1 <= vLigne ) and (y2 >= vLigne ) ) then
  672.         WinSetCursor( vColonne - x1 + x, vLigne - y1 + y );
  673.  
  674.       {-- En mode Write2View, la position d'affichage pour Write et ------}
  675.       {-- Writeln doit être recalée -------}
  676.  
  677.       if ( Write2View ) then { Est-on en mode Write2View ? }
  678.         begin
  679.           dec( WritelnX, x1 - x );
  680.           dec( WritelnY, y1 - y );
  681.           WritelnPtr := GetVioPtr( WritelnX, WritelnY );
  682.         end;
  683.  
  684.       x1 := x;    { Fixe les nouvelles coordonnées de la fenêtre }
  685.       x2 := x + Largeur - 1;
  686.       y1 := y;
  687.       y2 := y + Hauteur - 1;
  688.  
  689.       GetScr( x, y, x2, y2, @Buffer ); { Mémorise la zone recouverte }
  690.       PutScr( x, y, x2, y2, BufPtr );  { Puis affiche la nouvelle fenêtre }
  691.  
  692.       FreeMem( BufPtr, BufLen ); { Libère le buffer temporaire }
  693.     end;
  694.   inc( ViewX1, DeltaX );  { Déplace la zone de visualisation  }
  695.   inc( ViewX2, DeltaX );  
  696.   inc( ViewY1, DeltaY );
  697.   inc( ViewY2, DeltaY );
  698. end;
  699. {***************************************************************************
  700. *  WinInFront : ramène une fenêtre au premier plan                         *
  701. *                                                                          *
  702. **------------------------------------------------------------------------**
  703. *  Entrée : Key = Numéro de la fenêtre qui lui a été attribué par          *
  704. *                  l'une des fonctions WinOpen ou WinOpenShadow            *
  705. *  Sorties: True, si bon déroulement                                       *
  706. *           False, si pas assez de mémoire                                 *
  707. *  Variables globales : LigneOfs/R, ActWinPtr/RW, FirstWinPtr/RW, NbLig/R, *
  708. *            NbCol/R                                                       *
  709. ***************************************************************************}
  710.  
  711. function WinInFront( Key : integer ) : boolean;
  712.  
  713. var DummyWD : WINDES;  { Descripteur fictif }
  714. RunWiP,   { Pointe sur la liste des fenêtres }
  715.     WiP     : WIPTR;  { Pointe sur la fenêtre à traiter }
  716.     TempBuf,    { Buffer temporaire pour stocker une fenêtre }
  717.     WinBuf,     { Copie de la mémoire vidéo }
  718.     WinNrBuf,   { Contenu de la fenêtre à traiter }
  719.     VioCopy,    { Pointe sur la copie la mémoire vidéo }
  720.     Ancien,      { Pointe sur un buffer d'écran de travail }
  721.     Nouveau  : VPTR;  { Pointe sur le buffer du nouvel écran }
  722.     Nr,  { Numéro de la fenêtre à traiter dans la liste }
  723.     TempLen,    { Taille du buffer temporaire }
  724.     VioLen,     { Nombre d'octets de la mémoire vidéo }
  725.     AwiLen,     { Taille de la fenêtre à traiter }
  726.     i, j    : integer;   { Compteurs }
  727.  
  728. {-- les procédures locales Get et Put opèrent sur les différents }
  729. { buffers qui émulent la mémoire vidéo --}
  730.  
  731. procedure Get( x1, y1, x2, y2 : byte; VioPtr, BufPtr : pointer );
  732.  
  733. var nbytes : integer;   { Nombre d'octets à copier par ligne }
  734.  
  735. begin
  736.   nbytes := ( x2 - x1 + 1 ) shl 1;  { Octets par ligne }
  737.   inc( PTRREC( VioPtr ).Ofs, (x1 + y1 * NbCol) shl 1 );
  738.   while y1 <= y2 do  { Parcourt les lignes }
  739.     begin
  740.       Move( VioPtr^, BufPtr^, nbytes);
  741.       inc( PTRREC( VioPtr ).Ofs, LigneOfs );
  742.       inc( PTRREC( BufPtr ).Ofs, nbytes );
  743.       inc( y1 );  { Passe à la ligne suivante }
  744.     end;
  745. end;
  746.  
  747. procedure Put( x1, y1, x2, y2 : byte; VioPtr, BufPtr : pointer );
  748.  
  749. var nbytes : integer;   { Nombre d'octets à copier par ligne }
  750.  
  751. begin
  752.   nbytes := ( x2 - x1 + 1 ) shl 1;  { Octets par ligne }
  753.   inc( PTRREC( VioPtr ).Ofs, (x1 + y1 * NbCol) shl 1 );
  754.   while y1 <= y2 do   { Parcourt les lignes }
  755.     begin
  756.       Move( BufPtr^, VioPtr^, nbytes );
  757.       inc( PTRREC( VioPtr ).Ofs, LigneOfs );
  758.       inc( PTRREC( BufPtr ).Ofs, nbytes );
  759.       inc( y1 );  { Passe à la ligne suivante }
  760.     end;
  761. end;
  762.  
  763. {--------------------------------------------------------------------------}
  764.  
  765. begin
  766.  
  767.   {-- WiP va pointer sur la fenêtre à traiter ---------------}
  768.  
  769.   WiP := FirstWinPtr;   { WiP pointe d'abord sur la 1re fenêtre}
  770.   Nr := 0;              { qui porte le numéro 0 }
  771.   while WiP^.Handle <> Key do    { Est-ce le bon numéro ? }
  772.     begin  { Non }
  773.       WiP := WiP^.NextWin;   { Passe à la fenêtre suivante }
  774.       inc( Nr );     { Incrémente le numéro }
  775.     end;
  776.  
  777.   if ( WiP = ActWinPtr ) then { La fenêtre est-elle déjà au premier plan ? }
  778.     begin  { Oui, c'est terminé }
  779.       WinInFront := TRUE;
  780.       exit;
  781.     end;
  782.  
  783.   {-- Alloue 5 buffers pour stocker des parties de la mémoire vidéo  . ---}
  784.   {-- ( deux d'entre eux ne seront utilisés que plus tard ) --}
  785.  
  786.  
  787.   VioLen := NbLig * NbCol shl 1; { Nombres d'octets de la mémoire vidéo }
  788.   if MaxAvail <= VioLen * 5 then  { Assez de place pour 5 buffers ? }
  789.     begin  { Non }
  790.       WinInFront := false;  { Signale une erreur }
  791.       exit;  { et retourne à l'appelant }
  792.     end;
  793.  
  794.   {-- Il reste de la place sur le tas, on reporte la position du curseur --}
  795.   {-- et la zone de visualisation dans le descripteur de la fenêtre active }
  796.   DummyWD := Wip^;   { Mémorise le descripteur actuel }
  797.  
  798.   Wip^.curc   := vColonne;
  799.   Wip^.curl   := vLigne;
  800.   Wip^.ViewX1 := ViewX1;
  801.   Wip^.ViewY1 := ViewY1;
  802.   Wip^.ViewX2 := ViewX2;
  803.   Wip^.ViewY2 := ViewY2;
  804.  
  805.   {-- Fixe la position du curseur et la zone de visualisation de la nouvelle fenêtre -- }
  806.   with Wip^.NextWin^ do
  807.     begin
  808.       WinSetView( ViewX1, ViewY1, ViewX2, ViewY2 );
  809.       WinSetCursor( curc, curl );
  810.     end;
  811.  
  812.   {-- Reporte des données de la fenêtre à traiter dans son successeur------}
  813.   {-- actuel ------}
  814.  
  815.   with Wip^.NextWin^ do
  816.     begin
  817.       ViewX1 := DummyWD.ViewX1;
  818.       ViewY1 := DummyWD.ViewY1;
  819.       ViewX2 := DummyWD.ViewX2;
  820.       ViewY2 := DummyWD.ViewY2;
  821.       curc   := DummyWD.curc;
  822.       curl   := DummyWD.curl;
  823.     end;
  824.  
  825.   GetMem( Nouveau,  VioLen);  { Buffer servant à construire le nouvel écran }
  826.   GetMem( Ancien,   VioLen);  { Buffer servant à travailler sur les fenêtres }
  827.   GetMem( VioCopy, VioLen);  { Copie de la mémoire d'écran }
  828.  
  829.   {-- Copie le contenu de la mémoire vidéo dans les buffers VioCopy et Nouveau  }
  830.  
  831.   GetScr( 0, 0, NbCol-1, NbLig-1, VioCopy );
  832.   Move( VioCopy^, Nouveau^, VioLen ); { Sauvegarde du contenu de la RAM Video }
  833.  
  834.   {-- Ferme toutes les fenêtres situées au-dessus de la fenêtre de travail dans le buffer Nouveau -- }
  835.  
  836.   RunWip := ActWinPtr;  { Pointe sur la fenêtre active (=la dernière) }
  837.   for i:=NbWin-1 downto Nr+1 do  { Parcourt les fenêtres }
  838.     with RunWiP^ do
  839.       begin
  840.         Put( x1, y1, x2, y2, Nouveau, @Buffer );
  841.         RunWiP := LastWin; { Pointe sur la fenêtre précédente }
  842.       end;
  843.  
  844.   {-- Stocke le contenu de la fenêtre à traiter dans un buffer séparé désigné par WinNrBuf --}
  845.  
  846.   with WiP^ do
  847.     begin
  848.       if ( ( Attribut and WIN_OMBRE ) <> 0 ) then
  849.         begin  { Ne pas recopier l'ombre }
  850.           AwiLen := (x2-x1+1-ShadowX) * (y2-y1+1-ShadowY) shl 1; { Taille du buffer }
  851.           GetMem( WinNrBuf, AwiLen );  { Réserve de la place }
  852.           Get( x1, y1, x2-ShadowX, y2-ShadowY, Nouveau, WinNrBuf );
  853.           Put( x1, y1, x2, y2, Nouveau, @Buffer );  { Efface la fenêtre }
  854.         end
  855.       else  { Il n'y a pas d'ombre, donc recopie intégrale }
  856.         begin
  857.           AwiLen := (x2 - x1 + 1) * (y2 - y1 + 1) shl 1; { Taille du buffer }
  858.           GetMem( WinNrBuf, AwiLen ); { Réserve de la place }
  859.           Get( x1, y1, x2, y2, Nouveau, WinNrBuf ); { Transfère le contenu de la fenêtre dans le buffer }
  860.           Put( x1, y1, x2, y2, Nouveau, @Buffer ); { Efface la fenêtre }       end;
  861.     end;
  862.  
  863.   {-- Amène les fenêtres situées au-dessus de la fenêtre à traiter
  864.    dans le buffer Nouveau et stocke le contenu situé en-dessous }
  865.  
  866.   for i:=Nr+1 to NbWin-1 do  { Parcourt les fenêtres }
  867.     begin
  868.       Move( VioCopy^, Ancien^, VioLen );  { Copie la mémoire vidéo dans le buffer Ancien }
  869.       RunWiP := ActWinPtr;  { WiP pointe sur la dernière fenêtre }
  870.  
  871.       {-- Efface dans le buffer Ancien les fenêtres situées au-dessus de la fenêtre i ----------}
  872.       for j:=NbWin-1 downto i+1 do
  873.         with RunWiP^ do
  874.           begin
  875.             Put( x1, y1, x2, y2, Ancien, @Buffer );  { Efface la fenêtre }
  876.             RunWiP := LastWin; { WiP pointe sur la précédente }
  877.           end;
  878.  
  879.       {-- Recherche dans le buffer Nouveau le contenu situé au-dessous de--}
  880.       {-- la fenêtre i et copie ensuite la fenêtre i dans le buffer Nouveau }
  881.  
  882.       with RunWiP^ do
  883.         begin
  884.           Get( x1, y1, x2, y2, Nouveau, @Buffer );  { Contenu au-dessous de la fenêtre }
  885.  
  886.           {-- Si la fenêtre possède une ombre, il faut la recalculer }
  887.  
  888.           if ( ( Attribut and WIN_OMBRE ) <> 0 ) then
  889.             begin   { Reconstitue l'ombre }
  890.               TempLen := ( x2-x1+1-ShadowX ) * ( y2-y1+1-ShadowY ) shl 1;
  891.               GetMem( TempBuf, TempLen ); { Alloue un buffer temporaire }
  892.               Get( x1, y1, x2 - ShadowX, y2 - ShadowY, Ancien, TempBuf );
  893.               Put( x1, y1, x2 - ShadowX, y2 - ShadowY, Nouveau, TempBuf );
  894.               WinShadow( x2-ShadowX+1, y1+ShadowY, x2, y2, Nouveau );
  895.               WinShadow( x1+ShadowX, y2-ShadowY+1, x2-ShadowX, y2, Nouveau );
  896.             end
  897.           else  { Pas d'ombre à reconstituer }
  898.             begin
  899.               TempLen := (x2 - x1 + 1) * (y2 - y1 + 1) shl 1;
  900.               GetMem( TempBuf, TempLen ); { Alloue un buffer temporaire }
  901.               Get( x1, y1, x2, y2, Ancien, TempBuf );
  902.               Put( x1, y1, x2, y2, Nouveau, TempBuf );
  903.             end;
  904.           FreeMem( TempBuf, TempLen );  { Libère le buffer temporaire }
  905.         end;
  906.     end;
  907.  
  908.  
  909.   {-- Note le contenu situé en-dessous de la nouvelle première fenêtre et transfère cette fenêtre dans le buffer Nouveau }
  910.  
  911.   with WiP^ do
  912.     begin
  913.       Get( x1, y1, x2, y2, Nouveau, @Buffer );
  914.       if ( ( Attribut and WIN_OMBRE ) <> 0 ) then
  915.         begin  { Il y a une ombre à recalculer }
  916.           Put( x1, y1, x2-ShadowX, y2-ShadowY, Nouveau, WinNrBuf );
  917.           WinShadow( x2-ShadowX+1, y1+ShadowY, x2, y2, Nouveau );
  918.           WinShadow( x1+ShadowX, y2-ShadowY+1, x2-ShadowX, y2, Nouveau );
  919.         end
  920.       else  { Pas d'ombre }
  921.         Put( x1, y1, x2, y2, Nouveau, WinNrBuf );
  922.     end;
  923.  
  924.   {-- Déplace le descripteur de la fenêtre traitée à la fin de la liste chaînée -}
  925.  
  926.   Wip^.NextWin^.LastWin := WiP^.LastWin;
  927.   if WiP = FirstWinPtr then  { Est-ce que WIP était la première fenêtre ? }
  928.     FirstWinPtr := WiP^.NextWin  { Oui, c'est son successeur qui va être en première position }
  929.   else  { Non, WIP a encore un successeur }
  930.     Wip^.LastWin^.NextWin := WiP^.NextWin;
  931.  
  932.   Wip^.NextWin := nil;   { Plus de fenêtre après WIP }
  933.   Wip^.LastWin := ActWinPtr;  { le prédécesseur est l'ancienne fenêtre courante }
  934.   ActWinPtr^.NextWin := WiP;   { qui pointe maintenant sur WIP  }
  935.   ActWinPtr := WiP;
  936.   ActBufPtr := @Wip^.Buffer;
  937.  
  938.   {-- Affiche le nouvel écran --}
  939.  
  940.   PutScr( 0, 0, NbCol-1, NbLig-1, Nouveau );
  941.  
  942.   {-- Libère les buffers alloués    }
  943.  
  944.   FreeMem( WinNrBuf, AwiLen );
  945.   FreeMem( Nouveau,  VioLen);
  946.   FreeMem( Ancien,   VioLen);
  947.   FreeMem( VioCopy, VioLen);
  948.  
  949.   WinInFront := TRUE;        { Tout est bien qui finit bien }
  950. end;
  951.